package com.jin.spirng_boot_learn.sourceCode;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

public class LearnThreadLocal {

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        ThreadLocal<Integer> index5_place5 = null;
        ThreadLocal<Integer> index6_place6 = null;
        ThreadLocal<Integer> index5_place9 = null;
//        setupBefore();
//        showIndex();
        setupBefore();
        for (int i = 0; i < 32; i++) {
            if (i <= 2) {
                ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
                threadLocal.set(99);
                continue;
            }
            if (i == 3) {
                index5_place5 = new ThreadLocal<>();
                index5_place5.set(1);
                continue;
            }
            if (i == 10) {
                index6_place6 = new ThreadLocal<>();
                index6_place6.set(2);
                continue;
            }

            if (i == 19) {
                index5_place9 = new ThreadLocal<>();
                index5_place9.set(3);
                continue;
            }

            new ThreadLocal<>();// 滚动hash值

        }
        index5_place5.remove();
        index5_place9.get();



    }


    public static void setupBefore() throws NoSuchFieldException, IllegalAccessException {
        Class<ThreadLocal> threadLocalClass = ThreadLocal.class;
        Field nextHashCode = threadLocalClass.getDeclaredField("nextHashCode");
            nextHashCode.setAccessible(true);
        nextHashCode.set(ThreadLocal.class, new AtomicInteger());
    }

    public static void showIndex() throws NoSuchFieldException, IllegalAccessException{
            Class<ThreadLocal> threadLocalClass = ThreadLocal.class;

        for (int i = 0; i < 128; i++) {
            ThreadLocal<String> threadLocal = new ThreadLocal<>();

            Field threadLocalHashCode = threadLocalClass.getDeclaredField("threadLocalHashCode");
            threadLocalHashCode.setAccessible(true);

            Field nextHashCode = threadLocalClass.getDeclaredField("nextHashCode");
            nextHashCode.setAccessible(true);

            Integer o = (Integer) threadLocalHashCode.get(threadLocal);

            AtomicInteger atomicInteger = (AtomicInteger) nextHashCode.get(threadLocal);
            System.out.println(i + "---" + (o & (16 - 1))+"---"+o+"---"+Integer.toHexString(o)+"---"+atomicInteger.get());
        }
    }


}
